package com.netkit;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

public class NetkitClient {
	private String host;
	private int port;
	private final NetkitContext context;
	private ClientBootstrap bootstrap;
	private ChannelFactory channelFactory;

	public NetkitClient(String host, int port, NetkitContext context) {
		this.host = host;
		this.port = port;
		this.context = context;

		this.channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());

		this.bootstrap = new ClientBootstrap(this.channelFactory);

		this.bootstrap.setPipelineFactory(new NetkitChannelPipelineFactory(context));
	}

	public Session createSession() throws Exception {
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
		future = future.awaitUninterruptibly();
	
		if(future.isSuccess()){
			return context.createSession(future.getChannel(),null,null);
		}

		throw new Exception(future.getCause());
	}
	public void close() {
		this.context.release();

		this.channelFactory.releaseExternalResources();

		this.bootstrap.releaseExternalResources();
	}
	class CreateSessionSuccessListener implements ChannelFutureListener {
		private Object lock = new Object();
		private Session session;

		CreateSessionSuccessListener() {
		}
		public void operationComplete(ChannelFuture future) throws Exception {
			try {
				this.session = NetkitClient.this.context.createSession(future.getChannel(), null, null);
			} catch (Exception localException) {
			}
			synchronized (this.lock) {
				this.lock.notifyAll();
			}
		}

		public Session getSession() throws InterruptedException {
			join();
			return this.session;
		}

		private void join() throws InterruptedException {
			synchronized (this.lock) {
				while (this.session == null)
					this.lock.wait();
			}
		}
	}
}